package logic

import (
	"errors"
	"fmt"
	"time"

	"erp/model"

	"gorm.io/gorm"
)

type OrderService struct{ DB *gorm.DB }

func (s OrderService) CreateOrder(o *model.Order) error {
	return s.DB.Transaction(func(tx *gorm.DB) error {
		// 生成订单号
		if o.OrderNo == "" {
			o.OrderNo = s.generateOrderNo()
		}

		// 设置默认状态
		if o.Status == "" {
			o.Status = "待确认"
		}
		if o.PaymentStatus == "" {
			o.PaymentStatus = "待支付"
		}

		// stock check and decrement, and save product snapshot
		for i, it := range o.Items {
			var p model.Product
			if err := tx.First(&p, it.ProductID).Error; err != nil {
				return err
			}
			if p.Stock < it.Quantity {
				return errors.New("库存不足")
			}
			// 保存商品快照信息
			o.Items[i].ProductName = p.Name
			o.Items[i].Price = p.Price // 使用当前商品价格作为快照
		}
		if err := tx.Create(o).Error; err != nil {
			return err
		}
		for _, it := range o.Items {
			if err := tx.Model(&model.Product{}).Where("id = ?", it.ProductID).
				Update("stock", gorm.Expr("stock - ?", it.Quantity)).Error; err != nil {
				return err
			}
		}
		return nil
	})
}

// 更新订单状态
func (s OrderService) UpdateOrderStatus(id uint, status string) error {
	var order model.Order
	if err := s.DB.First(&order, id).Error; err != nil {
		return fmt.Errorf("订单不存在: %w", err)
	}

	// 验证状态值
	validStatuses := []string{"待确认", "已确认", "生产中", "待发货", "已发货", "已完成", "已取消"}
	valid := false
	for _, s := range validStatuses {
		if s == status {
			valid = true
			break
		}
	}
	if !valid {
		return fmt.Errorf("无效的订单状态: %s", status)
	}

	order.Status = status
	return s.DB.Save(&order).Error
}

// 更新支付状态
func (s OrderService) UpdatePaymentStatus(id uint, paymentStatus string) error {
	var order model.Order
	if err := s.DB.First(&order, id).Error; err != nil {
		return fmt.Errorf("订单不存在: %w", err)
	}

	// 验证支付状态值
	validStatuses := []string{"待支付", "部分支付", "已支付", "已退款"}
	valid := false
	for _, s := range validStatuses {
		if s == paymentStatus {
			valid = true
			break
		}
	}
	if !valid {
		return fmt.Errorf("无效的支付状态: %s", paymentStatus)
	}

	order.PaymentStatus = paymentStatus
	return s.DB.Save(&order).Error
}

// 删除订单
func (s OrderService) DeleteOrder(id uint) error {
	return s.DB.Transaction(func(tx *gorm.DB) error {
		var order model.Order
		if err := tx.Preload("Items").First(&order, id).Error; err != nil {
			return fmt.Errorf("订单不存在: %w", err)
		}

		// 恢复库存
		for _, item := range order.Items {
			if err := tx.Model(&model.Product{}).Where("id = ?", item.ProductID).
				Update("stock", gorm.Expr("stock + ?", item.Quantity)).Error; err != nil {
				return err
			}
		}

		// 删除订单项
		if err := tx.Where("order_id = ?", id).Delete(&model.OrderItem{}).Error; err != nil {
			return err
		}

		// 删除订单
		return tx.Delete(&order).Error
	})
}

// 获取订单统计
func (s OrderService) GetOrderStats() (map[string]interface{}, error) {
	var stats map[string]interface{} = make(map[string]interface{})

	// 总订单数
	var totalOrders int64
	if err := s.DB.Model(&model.Order{}).Count(&totalOrders).Error; err != nil {
		return nil, err
	}
	stats["total_orders"] = totalOrders

	// 今日订单数
	var todayOrders int64
	today := time.Now().Format("2006-01-02")
	if err := s.DB.Model(&model.Order{}).Where("DATE(created_at) = ?", today).Count(&todayOrders).Error; err != nil {
		return nil, err
	}
	stats["today_orders"] = todayOrders

	// 待确认订单数
	var pendingOrders int64
	if err := s.DB.Model(&model.Order{}).Where("status = ?", "待确认").Count(&pendingOrders).Error; err != nil {
		return nil, err
	}
	stats["pending_orders"] = pendingOrders

	// 待发货订单数
	var readyToShip int64
	if err := s.DB.Model(&model.Order{}).Where("status = ?", "待发货").Count(&readyToShip).Error; err != nil {
		return nil, err
	}
	stats["ready_to_ship"] = readyToShip

	// 总销售额
	var totalSales float64
	if err := s.DB.Model(&model.Order{}).Select("COALESCE(SUM(total_price), 0)").Scan(&totalSales).Error; err != nil {
		return nil, err
	}
	stats["total_sales"] = totalSales

	return stats, nil
}

// 生成订单号
func (s OrderService) generateOrderNo() string {
	now := time.Now()
	dateStr := now.Format("20060102")

	var count int64
	s.DB.Model(&model.Order{}).Where("order_no LIKE ?", dateStr+"%").Count(&count)

	return fmt.Sprintf("%s%04d", dateStr, count+1)
}

// 生成送货单
func (s OrderService) GenerateDeliveryNote(id uint, req struct {
	DeliveryDate    string  `json:"delivery_date"`
	DeliveryAddress string  `json:"delivery_address"`
	DeliveryContact string  `json:"delivery_contact"`
	DeliveryPhone   string  `json:"delivery_phone"`
	Warehouse       string  `json:"warehouse"`
	Packager        string  `json:"packager"`
	Shipper         string  `json:"shipper"`
	ShippingMethod  string  `json:"shipping_method"`
	Freight         float64 `json:"freight"`
	TaxRate         float64 `json:"tax_rate"`
	Discount        float64 `json:"discount"`
}) error {
	var order model.Order
	if err := s.DB.First(&order, id).Error; err != nil {
		return fmt.Errorf("订单不存在: %w", err)
	}

	// 生成送货单号
	if order.ShipmentNo == "" {
		order.ShipmentNo = s.generateShipmentNo()
	}

	// 更新送货单信息
	order.DeliveryDate = req.DeliveryDate
	order.DeliveryAddress = req.DeliveryAddress
	order.DeliveryContact = req.DeliveryContact
	order.DeliveryPhone = req.DeliveryPhone
	order.Warehouse = req.Warehouse
	order.Packager = req.Packager
	order.Shipper = req.Shipper
	order.ShippingMethod = req.ShippingMethod
	order.Freight = req.Freight
	order.TaxRate = req.TaxRate
	order.Discount = req.Discount

	// 计算税额和最终金额
	order.TaxAmount = (order.TotalPrice - order.Discount) * order.TaxRate / 100
	order.FinalAmount = order.TotalPrice - order.Discount + order.TaxAmount + order.Freight

	// 更新订单状态为待发货
	order.Status = "待发货"

	return s.DB.Save(&order).Error
}

// 获取送货单信息
func (s OrderService) GetDeliveryNote(id uint) (map[string]interface{}, error) {
	var order model.Order
	if err := s.DB.Preload("Items").First(&order, id).Error; err != nil {
		return nil, fmt.Errorf("订单不存在: %w", err)
	}

	deliveryNote := map[string]interface{}{
		"order":      order,
		"print_time": time.Now().Format("2006-01-02 15:04:05"),
		"company_info": map[string]string{
			"name":    "ERP系统",
			"address": "公司地址",
			"phone":   "联系电话",
			"fax":     "传真号码",
		},
	}

	return deliveryNote, nil
}

// 确认出库
func (s OrderService) ConfirmOutbound(id uint, req struct {
	OutboundDate string `json:"outbound_date"`
	Operator     string `json:"operator"`
	Notes        string `json:"notes"`
}) error {
	var order model.Order
	if err := s.DB.First(&order, id).Error; err != nil {
		return fmt.Errorf("订单不存在: %w", err)
	}

	// 检查订单状态
	if order.Status != "待发货" {
		return fmt.Errorf("订单状态不正确，当前状态: %s", order.Status)
	}

	// 更新出库信息
	order.Status = "已出库"
	order.Notes = req.Notes

	return s.DB.Save(&order).Error
}

// 确认发货
func (s OrderService) ConfirmShipment(id uint, req struct {
	ShipDate   string `json:"ship_date"`
	TrackingNo string `json:"tracking_no"`
	Carrier    string `json:"carrier"`
	Shipper    string `json:"shipper"`
	Notes      string `json:"notes"`
}) error {
	var order model.Order
	if err := s.DB.First(&order, id).Error; err != nil {
		return fmt.Errorf("订单不存在: %w", err)
	}

	// 检查订单状态
	if order.Status != "已出库" && order.Status != "待发货" {
		return fmt.Errorf("订单状态不正确，当前状态: %s", order.Status)
	}

	// 更新发货信息
	order.Status = "已发货"
	order.ShipmentNo = req.TrackingNo
	order.Notes = req.Notes

	return s.DB.Save(&order).Error
}

// 批量更新订单状态
func (s OrderService) BatchUpdateOrderStatus(orderIDs []uint, status string) error {
	// 验证状态值
	validStatuses := []string{"待确认", "已确认", "生产中", "待发货", "已出库", "已发货", "已完成", "已取消"}
	valid := false
	for _, s := range validStatuses {
		if s == status {
			valid = true
			break
		}
	}
	if !valid {
		return fmt.Errorf("无效的订单状态: %s", status)
	}

	return s.DB.Model(&model.Order{}).Where("id IN ?", orderIDs).Update("status", status).Error
}

// 生成送货单号
func (s OrderService) generateShipmentNo() string {
	now := time.Now()
	dateStr := now.Format("20060102")

	var count int64
	s.DB.Model(&model.Order{}).Where("shipment_no LIKE ?", "SH"+dateStr+"%").Count(&count)

	return fmt.Sprintf("SH%s%04d", dateStr, count+1)
}

// 获取送货单统计
func (s OrderService) GetDeliveryStats() (map[string]interface{}, error) {
	var stats map[string]interface{} = make(map[string]interface{})

	// 总送货单数
	var totalDeliveries int64
	if err := s.DB.Model(&model.Order{}).Where("shipment_no IS NOT NULL AND shipment_no != ''").Count(&totalDeliveries).Error; err != nil {
		return nil, err
	}
	stats["total_deliveries"] = totalDeliveries

	// 今日送货单数
	var todayDeliveries int64
	today := time.Now().Format("2006-01-02")
	if err := s.DB.Model(&model.Order{}).Where("shipment_no IS NOT NULL AND shipment_no != '' AND DATE(delivery_date) = ?", today).Count(&todayDeliveries).Error; err != nil {
		return nil, err
	}
	stats["today_deliveries"] = todayDeliveries

	// 待发货送货单数
	var pendingShipments int64
	if err := s.DB.Model(&model.Order{}).Where("shipment_no IS NOT NULL AND shipment_no != '' AND status = ?", "待发货").Count(&pendingShipments).Error; err != nil {
		return nil, err
	}
	stats["pending_shipments"] = pendingShipments

	// 已发货送货单数
	var shippedDeliveries int64
	if err := s.DB.Model(&model.Order{}).Where("shipment_no IS NOT NULL AND shipment_no != '' AND status = ?", "已发货").Count(&shippedDeliveries).Error; err != nil {
		return nil, err
	}
	stats["shipped_deliveries"] = shippedDeliveries

	// 总送货金额
	var totalDeliveryAmount float64
	if err := s.DB.Model(&model.Order{}).Where("shipment_no IS NOT NULL AND shipment_no != ''").Select("COALESCE(SUM(final_amount), 0)").Scan(&totalDeliveryAmount).Error; err != nil {
		return nil, err
	}
	stats["total_delivery_amount"] = totalDeliveryAmount

	return stats, nil
}

// 重新生成送货单号
func (s OrderService) RegenerateShipmentNo(id uint) error {
	var order model.Order
	if err := s.DB.First(&order, id).Error; err != nil {
		return fmt.Errorf("订单不存在: %w", err)
	}

	// 生成新的送货单号
	order.ShipmentNo = s.generateShipmentNo()
	return s.DB.Save(&order).Error
}
